package org.dromara.web.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.dromara.common.core.constant.GrantTypeConstants;
import org.dromara.common.core.domain.model.XcxLoginBody;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.system.domain.SysClient;
import org.dromara.web.client.HttpWxService;
import org.dromara.web.client.config.WxAppConfig;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.wx.domain.vo.WxUserVo;
import org.dromara.wx.service.IWxUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 小程序认证策略
 *
 * @author Michelle.Chung
 */
@Slf4j
@Service(GrantTypeConstants.XCX + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class XcxAuthStrategy{

    @Autowired
    private WxAppConfig wxAppConfig;

    @Resource
    private HttpWxService httpWxService;

    private final IWxUserService xhljIWxUserService;

    // TODO 待修改成返回 LoginVo
    public WxUserVo login(XcxLoginBody loginBody, SysClient client) {
        ValidatorUtils.validate(loginBody);
        // xcxCode 为 小程序调用 wx.login 授权后获取
        String xcxCode = loginBody.getXcxCode();
        String appid= loginBody.getAppid();
        String secret= loginBody.getSecret();

        String result=httpWxService.getResult(wxAppConfig.getAddress(),xcxCode,appid,secret,wxAppConfig.getGrantType());
        String openid=getOpenid(result);

        // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
        WxUserVo user = loadWxUserByOpenid(openid);
        return user;
    }

    private WxUserVo loadWxUserByOpenid(String openid) {

        // 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户
        // todo 自行实现 userService.selectUserByOpenid(openid);
        WxUserVo user = xhljIWxUserService.selectWxUserByOpenId(openid);
        if (ObjectUtils.isEmpty(user)) {
            log.info("小程序登录用户 openid：{} 不存在.", openid);
            log.info("开始创建默认微信用户 openid：{} ", openid);
            user =  xhljIWxUserService.createDefaultVo(openid);
            if(ObjectUtils.isNotEmpty(user)){
                log.info("创建默认微信用户 openid：{} 成功", openid);
            }else {
                throw new UserException("创建默认微信用户 openid：{} 失败", openid);
            }
        }
        return user;
    }
    private String getOpenid(String result) {
        String openid = null;
        if(StringUtils.isNotEmpty(result)){
            JSONObject jsonObject = JSON.parseObject(result);
            Object openidObj = jsonObject.get("openid");
            if(ObjectUtil.isNotNull(openidObj)){
                openid = openidObj.toString();
            }
            else{
                log.info("登录微信用户：{} code过期或错误code", openid);
                throw new UserException("wx.user.code.expire", openid);
            }
        }else {
            log.error("请求地址异常 => {} ", wxAppConfig.toString());
            throw new UserException("请求地址异常 => {}",wxAppConfig.toString());
        }
        return openid;
    }


}
